#include "..\include\Hero.hpp"
#include "../include/SpritesManager.hpp"
#include "../include/BackgroundManager.hpp"
#include "stdio.h"
#include <algorithm>

Hero::Hero(SpritesManager* _spritesManager, std::vector<int> _forbiddenTransfos){

	life = 3; // to fix
	lifeMax = 3;
	mana = 0;
	manaMax = 3;
	transformID = 0; // Human (default)
	screen = BOTTOM;
	spritesManager = _spritesManager;
	initTransformations();
	idSpriteDisplay = 0;
	actualFrame=0;
	frameRate = 8;
	jumpDirection = TO_GROUND;
	posJump = 0;
	heightJump = 45;
	speedJump = 2;
	isJumping = false;
	nbFrameFlying = 0;
	doubleJump = false;
	isFlying = false;
	isInvincible = false;
	invincibleTicks = 0;

	flyDirection = GO_UP;
	nbFrameClimbing = 20;
	timeClimbing = 0;

	forbiddenTransfos = _forbiddenTransfos;
}

Hero::~Hero(void){

	for(int i =0; i <charDatas.size(); i++){

		for(int j = 0; j < charDatas.at(i)->animImages.size(); j++) delete charDatas.at(i)->animImages.at(j);
		for(int k = 0; k < charDatas.at(i)->animImages.size(); k++) delete charDatas.at(i)->animImages_top.at(k);
		delete charDatas.at(i);
	}
}

void Hero::initTransformations(){
	// Human state
	CharacterData* humanData = new CharacterData();
	humanData->strength = 2;
	humanData->defense = 2;
	humanData->speed = 2;
	humanData->bonuses = NO_BONUS;
	humanData->penalties = NO_PENALTY;
	Sprite* image1 = new Sprite();
	image1->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->HUMAN_1, spritesManager->HUMAN_PAL, OTHER);
	humanData->animImages.push_back(image1);
	humanData->firstOAM_ID = image1->OAM_ID;
	Sprite* image2 = new Sprite();
	image2->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->HUMAN_2, spritesManager->HUMAN_PAL, OTHER);
	humanData->animImages.push_back(image2);
	Sprite* image3 = new Sprite();
	image3->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->HUMAN_3, spritesManager->HUMAN_PAL, OTHER);
	humanData->animImages.push_back(image3);

	image1 = new Sprite();
	image1->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->HUMAN_1_TOP, spritesManager->HUMAN_PAL_TOP, OTHER);
	humanData->animImages_top.push_back(image1);
	humanData->firstOAM_TOP_ID = image1->OAM_ID;
	image2 = new Sprite();
	image2->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->HUMAN_2_TOP, spritesManager->HUMAN_PAL_TOP, OTHER);
	humanData->animImages_top.push_back(image2);
	image3 = new Sprite();
	image3->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->HUMAN_3_TOP, spritesManager->HUMAN_PAL_TOP, OTHER);
	humanData->animImages_top.push_back(image3);

	charDatas.push_back(humanData);

	// Vampire transformation
	CharacterData* vampireData = new CharacterData();
	vampireData->strength = 3;
	vampireData->defense = 2;
	vampireData->speed = 4;
	vampireData->bonuses = NO_BONUS;
	vampireData->penalties = SUN_SENSIBILITY;
	image1 = new Sprite();
	image1->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->VAMPIRE_1, spritesManager->VAMPIRE_PAL, OTHER);
	vampireData->animImages.push_back(image1);
	vampireData->firstOAM_ID = image1->OAM_ID;
	image2 = new Sprite();
	image2->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->VAMPIRE_2, spritesManager->VAMPIRE_PAL, OTHER);
	vampireData->animImages.push_back(image2);
	image3 = new Sprite();
	image3->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->VAMPIRE_3, spritesManager->VAMPIRE_PAL, OTHER);
	vampireData->animImages.push_back(image3);

	image1 = new Sprite();
	image1->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->VAMPIRE_1_TOP, spritesManager->VAMPIRE_PAL_TOP, OTHER);
	vampireData->animImages_top.push_back(image1);
	vampireData->firstOAM_TOP_ID = image1->OAM_ID;
	image2 = new Sprite();
	image2->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->VAMPIRE_2_TOP, spritesManager->VAMPIRE_PAL_TOP, OTHER);
	vampireData->animImages_top.push_back(image2);
	image3 = new Sprite();
	image3->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->VAMPIRE_3_TOP, spritesManager->VAMPIRE_PAL_TOP, OTHER);
	vampireData->animImages_top.push_back(image3);
	charDatas.push_back(vampireData);

	// Zombie transformation
	CharacterData* zombieData = new CharacterData();
	zombieData->strength = 3;
	zombieData->defense = 3;
	zombieData->speed = 1;
	zombieData->bonuses = LIFE_STEAL;
	zombieData->penalties = NO_PENALTY;
	image1 = new Sprite();
	image1->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->ZOMBIE_1, spritesManager->ZOMBIE_PAL, OTHER);
	zombieData->animImages.push_back(image1);
	zombieData->firstOAM_ID = image1->OAM_ID;
	image2 = new Sprite();
	image2->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->ZOMBIE_2, spritesManager->ZOMBIE_PAL, OTHER);
	zombieData->animImages.push_back(image2);
	image3 = new Sprite();
	image3->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->ZOMBIE_3, spritesManager->ZOMBIE_PAL, OTHER);
	zombieData->animImages.push_back(image3);	

	image1 = new Sprite();
	image1->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->ZOMBIE_1_TOP, spritesManager->ZOMBIE_PAL_TOP, OTHER);
	zombieData->animImages_top.push_back(image1);
	zombieData->firstOAM_TOP_ID = image1->OAM_ID;
	image2 = new Sprite();
	image2->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->ZOMBIE_2_TOP, spritesManager->ZOMBIE_PAL_TOP, OTHER);
	zombieData->animImages_top.push_back(image2);
	image3 = new Sprite();
	image3->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->ZOMBIE_3_TOP, spritesManager->ZOMBIE_PAL_TOP, OTHER);
	zombieData->animImages_top.push_back(image3);
	charDatas.push_back(zombieData);


	// Bat transformation
	CharacterData* batData = new CharacterData();
	batData->strength = 3;
	batData->defense = 2;
	batData->speed = 5;
	batData->bonuses = FLY;
	batData->penalties = SUN_SENSIBILITY;
	image1 = new Sprite();
	image1->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->BAT_1, spritesManager->BAT_PAL, OTHER);
	batData->animImages.push_back(image1);
	batData->firstOAM_ID = image1->OAM_ID;
	image2 = new Sprite();
	image2->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->BAT_2, spritesManager->BAT_PAL, OTHER);
	batData->animImages.push_back(image2);
	image3 = new Sprite();
	image3->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->BAT_3, spritesManager->BAT_PAL, OTHER);
	batData->animImages.push_back(image3);

	image1 = new Sprite();
	image1->display(spritesManager, TOP, 5, 128,OBJPRIORITY_2,  spritesManager->BAT_1_TOP, spritesManager->BAT_PAL_TOP, OTHER);
	batData->animImages_top.push_back(image1);
	batData->firstOAM_TOP_ID = image1->OAM_ID;
	image2 = new Sprite();
	image2->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->BAT_2_TOP, spritesManager->BAT_PAL_TOP, OTHER);
	batData->animImages_top.push_back(image2);
	image3 = new Sprite();
	image3->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->BAT_3_TOP, spritesManager->BAT_PAL_TOP, OTHER);
	batData->animImages_top.push_back(image3);
	charDatas.push_back(batData);

	// FatZombie transformation
	CharacterData* fatZombieData = new CharacterData();
	fatZombieData->strength = 5;
	fatZombieData->defense = 4;
	fatZombieData->speed = 2;
	fatZombieData->bonuses = LIFE_STEAL;
	fatZombieData->penalties = LITTLE_JUMP;
	image1 = new Sprite();
	image1->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->FATZOMBIE_1, spritesManager->FATZOMBIE_PAL, OTHER);
	fatZombieData->animImages.push_back(image1);
	fatZombieData->firstOAM_ID = image1->OAM_ID;
	image2 = new Sprite();
	image2->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->FATZOMBIE_2, spritesManager->FATZOMBIE_PAL, OTHER);
	fatZombieData->animImages.push_back(image2);
	image3 = new Sprite();
	image3->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->FATZOMBIE_3, spritesManager->FATZOMBIE_PAL, OTHER);
	fatZombieData->animImages.push_back(image3);

	image1 = new Sprite();
	image1->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->FATZOMBIE_1_TOP, spritesManager->FATZOMBIE_PAL_TOP, OTHER);
	fatZombieData->animImages_top.push_back(image1);
	fatZombieData->firstOAM_TOP_ID = image1->OAM_ID;
	image2 = new Sprite();
	image2->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->FATZOMBIE_2_TOP, spritesManager->FATZOMBIE_PAL_TOP, OTHER);
	fatZombieData->animImages_top.push_back(image2);
	image3 = new Sprite();
	image3->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->FATZOMBIE_3_TOP, spritesManager->FATZOMBIE_PAL_TOP, OTHER);
	fatZombieData->animImages_top.push_back(image3);
	charDatas.push_back(fatZombieData);

	// Werewolf transformation
	CharacterData* werewolfData = new CharacterData();
	werewolfData->strength = 4;
	werewolfData->defense = 3;
	werewolfData->speed = 4;
	werewolfData->bonuses = NO_BONUS;
	werewolfData->penalties = SUN_SENSIBILITY;
	image1 = new Sprite();
	image1->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->WEREWOLF_1, spritesManager->WEREWOLF_PAL, OTHER);
	werewolfData->animImages.push_back(image1);
	werewolfData->firstOAM_ID = image1->OAM_ID;
	image2 = new Sprite();
	image2->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->WEREWOLF_2, spritesManager->WEREWOLF_PAL, OTHER);
	werewolfData->animImages.push_back(image2);
	image3 = new Sprite();
	image3->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->WEREWOLF_3, spritesManager->WEREWOLF_PAL, OTHER);
	werewolfData->animImages.push_back(image3);

	image1 = new Sprite();
	image1->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->WEREWOLF_1_TOP, spritesManager->WEREWOLF_PAL_TOP, OTHER);
	werewolfData->animImages_top.push_back(image1);
	werewolfData->firstOAM_TOP_ID = image1->OAM_ID;
	image2 = new Sprite();
	image2->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->WEREWOLF_2_TOP, spritesManager->WEREWOLF_PAL_TOP, OTHER);
	werewolfData->animImages_top.push_back(image2);
	image3 = new Sprite();
	image3->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->WEREWOLF_3_TOP, spritesManager->WEREWOLF_PAL_TOP, OTHER);
	werewolfData->animImages_top.push_back(image3);
	charDatas.push_back(werewolfData);

	// Hunter transformation
	CharacterData* hunterData = new CharacterData();
	hunterData->strength = 4;
	hunterData->defense = 3;
	hunterData->speed = 3;
	hunterData->bonuses = LIFE_STEAL;
	hunterData->penalties = SHORT_TRANSFORMATION;
	image1 = new Sprite();
	image1->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->HUNTER_1, spritesManager->HUNTER_PAL, OTHER);
	hunterData->animImages.push_back(image1);
	hunterData->firstOAM_ID = image1->OAM_ID;
	image2 = new Sprite();
	image2->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->HUNTER_2, spritesManager->HUNTER_PAL, OTHER);
	hunterData->animImages.push_back(image2);
	image3 = new Sprite();
	image3->display(spritesManager, BOTTOM, 5, 128, OBJPRIORITY_2, spritesManager->HUNTER_3, spritesManager->HUNTER_PAL, OTHER);
	hunterData->animImages.push_back(image3);

	image1 = new Sprite();
	image1->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->HUNTER_1_TOP, spritesManager->HUNTER_PAL_TOP, OTHER);
	hunterData->animImages_top.push_back(image1);
	hunterData->firstOAM_TOP_ID = image1->OAM_ID;
	image2 = new Sprite();
	image2->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->HUNTER_2_TOP, spritesManager->HUNTER_PAL_TOP, OTHER);
	hunterData->animImages_top.push_back(image2);
	image3 = new Sprite();
	image3->display(spritesManager, TOP, 5, 128, OBJPRIORITY_2, spritesManager->HUNTER_3_TOP, spritesManager->HUNTER_PAL_TOP, OTHER);
	hunterData->animImages_top.push_back(image3);
	charDatas.push_back(hunterData);


	initSpriteVisibility(0);
}

// pos : TOP = 0 , BOTTOM = 1
void Hero::initSpriteVisibility( unsigned int _transformID ){
	for(unsigned int i= 0; i<charDatas.size() ; i++){
		for(unsigned int j=0; j<3; j++){
			if(screen == BOTTOM){
				if(i == _transformID){
					spritesManager->oam->oamBuffer[charDatas[i]->firstOAM_ID+j].isHidden = false;
				}
				else{
					spritesManager->oam->oamBuffer[charDatas[i]->firstOAM_ID+j].isHidden = true;
				}
				spritesManager->oamSub->oamBuffer[charDatas[i]->firstOAM_TOP_ID+j].isHidden = true;
			}
			else{
				if(i == _transformID){
					spritesManager->oamSub->oamBuffer[charDatas[i]->firstOAM_TOP_ID+j].isHidden = false;
				}
				else{
					spritesManager->oamSub->oamBuffer[charDatas[i]->firstOAM_TOP_ID+j].isHidden = true;
				}
				spritesManager->oam->oamBuffer[charDatas[i]->firstOAM_ID+j].isHidden = true;
			}
		}
	}
}

void Hero::animate(){
	actualFrame++;
	if(actualFrame == frameRate){
		if(screen == BOTTOM)
			spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+idSpriteDisplay].isHidden = true;
		else
			spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+idSpriteDisplay].isHidden = true;

		idSpriteDisplay++;
		if(idSpriteDisplay == 3)
			idSpriteDisplay = 0;

		if(screen == BOTTOM)
			spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+idSpriteDisplay].isHidden = false;
		else
			spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+idSpriteDisplay].isHidden = false;

		actualFrame = 0;
	}

	if(isJumping){
		if(screen == BOTTOM){
			if(doubleJump){
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = true;
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].isHidden = true;
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = false;
			}
			else{
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = false;
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].isHidden = true;
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = true;
			}
		} else {
			if(doubleJump){
				spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID].isHidden = true;
				spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+1].isHidden = true;
				spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+2].isHidden = false;
			}
			else{
				spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID].isHidden = false;
				spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+1].isHidden = true;
				spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+2].isHidden = true;
			}
		}

		if(jumpDirection == GO_UP && posJump < heightToGet ){
			if(screen==BOTTOM){
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].y -= speedJump;
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].y -= speedJump;
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].y -= speedJump;
			}else if(screen==TOP){
				//Si l'on ne depasse pas l'ecran du haut
				if(spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID].y - speedJump > 1){
					spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID].y -= speedJump;
					spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+1].y -= speedJump;
					spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+2].y -= speedJump;
				}
				else jumpDirection = STAY_FLYING;
			}
			posJump+=2;
		}
		if(jumpDirection == GO_UP && posJump >= heightToGet){
			posJump = heightToGet;
			jumpDirection = STAY_FLYING;
		}
		if(jumpDirection == STAY_FLYING && nbFrameFlying < 10){
			nbFrameFlying++;
		}
		if(jumpDirection == STAY_FLYING && nbFrameFlying == 10){
			nbFrameFlying = 0;

			jumpDirection = GO_DOWN;/////////////////////////
			posJump = 0;
			//isJumping = false;//

			//jumpDirection = GO_UP;//
			//spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].y = 128;
			//spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].y = 128;
			//spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].y = 128;
		}

		/*if(jumpDirection == GO_DOWN && screen == TOP){
		spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID].y += speedJump;
		spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+1].y += speedJump;
		spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+2].y += speedJump;    
		posJump--;
		}
		if(jumpDirection == GO_DOWN && screen == BOTTOM){
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].y += speedJump;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].y += speedJump;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].y += speedJump;   
		posJump--;
		}*/
		/*
		if( screen == BOTTOM && jumpDirection == GO_DOWN  &&  posJump <= 0  &&  spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].y <= 128  ){
		posJump = 0;
		isJumping = false;
		doubleJump = false;
		jumpDirection = GO_UP;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].y = 128;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].y = 128;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].y = 128;
		}*/
	}


	if(isFlying){
		if(screen == TOP){
			if(flyDirection == GO_UP && timeClimbing <= nbFrameClimbing  ){
				spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID].y -= 2;
				spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+1].y -= 2;
				spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+2].y -= 2;

				int y = spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+2].y;
				if(  y < 4 ){
					spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID].y = 2;
					spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+1].y = 2;
					spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+2].y = 2;
				}

				timeClimbing++;
			}
			if(flyDirection == GO_UP && timeClimbing > nbFrameClimbing){
				timeClimbing = 0;
				flyDirection = GO_DOWN;
			}
			if(flyDirection == GO_DOWN  ){
				spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID].y += 1;
				spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+1].y += 1;
				spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+2].y += 1;
			}
		}
		else{
			if(flyDirection == GO_UP && timeClimbing <= nbFrameClimbing ){
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].y -= 2;
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].y -= 2;
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].y -= 2;
				timeClimbing++;
			}
			if(flyDirection == GO_UP && timeClimbing > nbFrameClimbing){
				timeClimbing = 0;
				flyDirection = GO_DOWN;
			}
			if(flyDirection == GO_DOWN && spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].y <= 128 ){
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].y += 1;
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].y += 1;
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].y += 1;
			}
		}
	}


	if(isInvincible){

		if(invincibleTicks < 20 ){
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = true;
		}

		else if(invincibleTicks < 30 ){
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = false;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = true;
		}

		else if(invincibleTicks < 40 ){
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = true;
		}

		else if(invincibleTicks < 50 ){
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].isHidden = false;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = true;
		}

		else if(invincibleTicks < 60 ){
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = true;
		}

		else if(invincibleTicks < 70 ){
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = false;
		}

		else if(invincibleTicks < 80 ){
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = true;
		}

		else if(invincibleTicks < 90 ){
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = false;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = true;
		}

		else if(invincibleTicks < 100 ){
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].isHidden = true;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = true;
		}


	}

	detectSwitchScreen();
}

void Hero::detectSwitchScreen(){

	int yTop = spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID].y;
	int yBot = spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].y;

	if(screen == TOP){
		if(yTop > 192){
			screen = BOTTOM;
			spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].y = 0;
			spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].y = 0;
			spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].y = 0;
			if(doubleJump)
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = true;
			else
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = true;	
			initSpriteVisibility(transformID);
		}
		if(yTop > 170 && yTop < 192){
			if(doubleJump)
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = false;
			else
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = false;	
			spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].y = 255 - (192 - yTop);
			spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].y = 255 - (192 - yTop);
			spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].y = 255 - (192 - yTop);
		}
		if(yTop > 0 && yTop < 170){
			if(doubleJump)
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].isHidden = true;
			else
				spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].isHidden = true;
		}
	}
	if(screen == BOTTOM){ 
		if(yBot > 192 && yBot < 255){
			screen = TOP;
			spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID].y = 191;
			spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+1].y = 191;
			spritesManager->oamSub->oamBuffer[charDatas[transformID]->firstOAM_TOP_ID+2].y = 191;
			initSpriteVisibility(transformID);
		}
	}

}

void Hero::jump(){
	// allow the double jump if the player is not in the Fat Zombie transformation (transformID == 4) or Human ( id == 0) and the player is on the top of his jump or falling down
	if(!doubleJump && isJumping && transformID != 4  && transformID != 0 && ( jumpDirection == STAY_FLYING || jumpDirection == GO_DOWN ) ){
		doubleJump = true;
		jumpDirection = GO_UP;
		nbFrameFlying = 0;
		heightToGet = heightJump + posJump;
		isJumping = true;
	}
	else if(!doubleJump && transformID != 4  && transformID != 0){
		jumpDirection = GO_UP;
		heightToGet = heightJump;
		isJumping = true;
	}

	else if(!isJumping){
		jumpDirection = GO_UP;
		heightToGet = heightJump;
		isJumping = true;
	}


}

void Hero::fly(){
	isFlying = true;
	flyDirection = GO_UP; 
	nbFrameFlying = 0;
}

void Hero::updateMana(){

	if(mana < 3)mana++;

}

void Hero::updateHealth(int delta){

	if(delta >0 && life < lifeMax)life ++;
	if(delta <0 && life > 0)life --;
//	std::cout << "life " << life<< std::endl;

}

void Hero::transformUP(BackgroundManager* backgroundManager){
	//iprintf("TRANSFORMATION UP  ; %d  ?=  %d \n", mana, manaMax);
	// pour pouvoir se transformer, le joueur doit avoir sa barre de mana remplie
	if( mana == manaMax ){ 
		switch(transformID){
		case 0: // Human
			transform(1, backgroundManager); // -> Vampire
			break;
		case 1: // Vampire 
			transform(5, backgroundManager); // -> Werewolf
			break;
		case 2: // Zombie
			transform(6, backgroundManager); // -> Hunter
			break;
		}
	}
}

void Hero::transformDOWN(BackgroundManager* backgroundManager){
	//iprintf("TRANSFORMATION DOWN  ; %d  ?=  %d \n", mana, manaMax);
	// pour pouvoir se transformer, le joueur doit avoir sa barre de mana remplie
	if( mana == manaMax ){ 
		switch(transformID){
		case 0: // Human
			transform(2, backgroundManager); // -> Zombie
			break;
		case 1: // Vampire 
			transform(3, backgroundManager); // -> Bat
			break;
		case 2: // Zombie
			transform(4, backgroundManager); // -> Fat Zombie
			break;
		default :
			//iprintf("echec transformation");
			break;
		}
	}
	else{
		//iprintf("echec transformation - mana");
	}
}


void Hero::transform(unsigned int _transformID, BackgroundManager* backgroundManager){
	iprintf("transformID : %d\n", _transformID);

	std::vector<int>::iterator it = std::find(forbiddenTransfos.begin(), forbiddenTransfos.end(), _transformID);
	if (it == forbiddenTransfos.end()){
		int y = spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].y;
		transformID = _transformID;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID].y = y;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+1].y = y;
		spritesManager->oam->oamBuffer[charDatas[transformID]->firstOAM_ID+2].y = y;
		initSpriteVisibility(transformID);
		if(transformID !=0 )mana = 0;
		spritesManager->spriteSpeed = spritesManager->speedBase / charDatas[transformID]->speed; 
		backgroundManager->backgroundSpeed = spritesManager->spriteSpeed*2;

	}
	else {
		iprintf("forbidden transfo\n");
	}

}

void Hero::eatEnemy(){
}

void Hero::loadCharData(){
}